#!/bin/bash

#  cmdex: the small script do something to help you.
#  you can execute command in every directory and its subdirectory.
#  designer: Swaper@RainStudio

slfName=$(basename $0)
oldIFS=$IFS

curPath=""
strCmd=""
strArgs=""
inCmd=""
inArgs=""

showDir=0
showNumOfDirs=0
NumOfDirs=0
hasObjDir=0
hasCmd=0

IFS=""
for i in $*; do
  if [ ${i:0:3} == "/c:" ]; then
    strCmd=${i:3}
    inCmd=$i
    hasCmd=1
  fi
  if [ ${i:0:3} == "/a:" ]; then
      if [ -z $strArgs ]; then
        strArgs=${i:3}
        inArgs=$i
      else
        strArgs="$strArgs ${i:3}"
        inArgs="$inArgs ${i:3}"
      fi
  fi
  if [ ${i:0:2} == "/d" ]; then
    showDir=1
  fi
  if [ ${i:0:2} == "/n" ]; then
    showNumOfDirs=1
  fi
done

if [ $hasCmd -eq 0 ]; then
  echo "$slfName: usage: $slfName: path /c:command /a:arg1 /a:arg2..."
  echo "option /d show working directory."
  echo "examples:"
  echo "  $slfName /home/myhome /c:ls"
  echo "  $slfName /home/myhome /c:ls /a:-l"
  echo "hint:"
  echo "if you have some arguments include space such as"
  echo "  \"01234 56789\""
  echo "  \"a b c\""
  echo "you can write them into a script as a command."
  IFS=$oldIFS
  exit 1;
fi

IFS=""
dirs -c
pushd +0 > /dev/null
curPath=$(dirs -l +0)

fcCmdex( )
{
  if [ ${i:0:3} != "/c:" ] && [ ${i:0:3} != "/a:" ] &&
    [ ${i:0:2} != "/d" ]; then
    if [ -d $i ] && ! [ -L $i ] ; then
      if [ $showDir -eq 1 ]; then
        echo $i
      fi
      cd $i
      IFS=" "
      $strCmd $strArgs
      IFS=""
      cd $curPath
      for j in $i/*; do
        if [ -d $j ] && ! [ -L $j ]; then
          if [ $showDir -eq 1 ]; then
            ($0 $j $inCmd $inArgs /d)
          else
            ($0 $j $inCmd $inArgs)
          fi
          NumOfDirs=$[$NumOfDirs+$?]
        fi
      done
      for j in $i/.*; do
        if [ $j != "$i/." ] && [ $j != "$i/.." ] &&
          [ -d $j ] && ! [ -L $j ]; then
          if [ $showDir -eq 1 ]; then
            ($0 $j $inCmd $inArgs /d)
          else
            ($0 $j $inCmd $inArgs)
          fi
          NumOfDirs=$[$NumOfDirs+$?]
        fi
      done
    NumOfDirs=$[$NumOfDirs+1]
    fi
    hasObjDir=1
  fi
}

for i in $*; do
  fcCmdex
done

if [ $hasObjDir -eq 0 ]; then
  i=$curPath
  fcCmdex
fi

if [ $showNumOfDirs -eq 1 ]; then
  echo $NumOfDirs
fi

IFS=$oldIFS

exit $NumOfDirs
